import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.Point;
import java.awt.LayoutManager;
import java.awt.GridBagConstraints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;

import javax.swing.*;
import javax.swing.border.Border;


public class GraphView extends JPanel
{
	private Controller control;
	private Color[] colors={Color.black, Color.red, Color.blue, Color.green, Color.orange, Color.magenta, Color.cyan, Color.yellow, Color.pink, Color.gray};
	private GridBagConstraints forGraph;
	private JPanel key;
	
	public GraphView(Controller myControl)
	{
		control=myControl;
		this.setBorder(BorderFactory.createLoweredBevelBorder());
		
		setMinimumSize(new Dimension(300, 300));
		setPreferredSize(new Dimension(500, 500));
		setMaximumSize(new Dimension(Short.MAX_VALUE, Short.MAX_VALUE));
		forGraph = new GridBagConstraints();
		key=new JPanel();
		key.setMaximumSize(new Dimension(new Integer(500), new Integer(100)));
		key.setMinimumSize(new Dimension(new Integer(100), new Integer(100)));
		key.setBorder(BorderFactory.createBevelBorder(4));
		setUpKey();
		
		forGraph.gridx = 10;
		forGraph.gridy = 10;
		forGraph.ipadx = 100;
		forGraph.ipady = 100;
		//forGraph.insets = new Insets(100, 100, 100, 100);
		key.validate();
		repaint();
	}
	
	public void updateColors(int place, Color color)
	{
		if (place<colors.length)
		{
			colors[place]=color;
			return;
		}
		Color[] newColors=new Color[place-1];
		newColors[place]=color;
		for (int i=0;i<place;i++)
		{
			newColors[i] = colors[i % colors.length];
		}
		colors=newColors;
		validate();
		repaint();
	}
	
	public void paintComponent(Graphics g)
	{
		super.paintComponent(g);
		g.fillRect(xAxisStartX(), xAxisStartY(), xAxisLength(), 2);	//x-axis
		g.fillRect(yAxisStartX(), yAxisStartY(), 2, yAxisHeight());	//y-axis
		g.drawString("Time elapsed", (int)(getSize().width*.04), (int)(getSize().height*.06)); //y-axis label
		g.drawString("Size of data set", (int)(getSize().width*.42), (int)(getSize().height*.95));  //x-axis label
		int place=0;
		ArrayList<ArrayList<Point>> dataSets=control.getData(); 
		//test code:
		/*ArrayList<Point> testSet = new ArrayList<Point>();
		testSet.add(new Point(0,0));
		testSet.add(new Point(1,1));
		dataSets.add(testSet);*/
		try
		{	
			/*if (dataSets.size() == 0){
				//System.out.println("Data set size is 0");
			}*/
			for (ArrayList<Point> points:dataSets)
			{
				int color = place%colors.length;
				g.setColor(colors[color]);
				place++;
				for (Point point:points)
				{	
					Point actualPoint=getActualPoint(point);
					g.fillRect(actualPoint.x, actualPoint.y, 1, 2);
				}
			}
			setUpKey();
			//test ArrayList for key:
			
			//key.validate();
			//add(key);
			
			//addToKey(control.getOptionsPicked()); //needs to be written in ConsoleController - accessor returning ConsoleState's optionsPicked
			key.validate();
			repaint();
		}
		catch (Exception e)
		{ 
			e.printStackTrace();
		}
	}
	
	public JPanel getKeyPanel()
	{
		return key;
	}
	
	public JPanel setUpKey()
	{
		ArrayList<String> labels = control.getLabels();	//labels = control.getOptionsPicked();
		
		LayoutManager gLayout = new GridLayout(labels.size()+1, 2); //chose a different manager to be able to vary column width
		//key = new JPanel(gLayout);
		clearKey();
		key.setLayout(gLayout);
		//int i = 0;
		for(int i = 0; i < labels.size(); i++)
		{
			Color c = colors[i % colors.length];
			JPanel keyColor = new JPanel();
			keyColor.addMouseListener(new ColorManager(i, this));
			keyColor.setBackground(c);
			key.add(keyColor);
			JLabel keyLabel = new JLabel();
			keyLabel.setText("- " + /*dataSet*/ labels.get(i));
			key.add(keyLabel);
			//i++;
		}
		
		key.setMaximumSize(new Dimension(new Integer(500), new Integer(100 + labels.size() * 50)));
		key.setMinimumSize(new Dimension(new Integer(100), new Integer(100 + labels.size() * 50)));
		JButton clearGraph=new JButton("Clear Graph");
		clearGraph.addActionListener(getGraphClear());
		key.add(clearGraph);
		key.add(clearGraph);
		key.validate();
		return key;
	}
	private void clearKey() {
		Component[] components=key.getComponents();
		for (int i=0;i<components.length;i++)
		{
			key.remove(components[i]);
		}
	}

	//WE NEED TO FIX THIS BTDUBS
	private Point getActualPoint(Point point)
	{
		int actualX=point.x;
		//int actualY=getSize().height-point.y;
		int actualY=point.y;
		actualY=(int)(((double)actualY/control.getLargestData())*(yAxisHeight()));
		actualX=(int)(((double)actualX/control.getLargestSize())*(xAxisLength()));
		//actualY=actualY/1000;
		//actualY*=10;
		actualY+=yAxisStartY()+2;
		//actualY=(int)(((double)actualX/control.getLargestData())*(yAxisHeight()));
		actualY=getSize().height-actualY;
		actualX+=xAxisStartX();
		Point newPoint=new Point(actualX, actualY);
		return newPoint;
	}
	
	private int xAxisLength()
	{
		return (int)(getSize().width*.8);
	}
	
	private int xAxisStartX()
	{
		return (int)(getSize().width*.1);
	}
	
	private int xAxisStartY()
	{
		return (int)(getSize().height*.9);
	}
	
	private int yAxisHeight()
	{
		return (int)(getSize().height*.8);
	}
	
	private int yAxisStartX()
	{
		return (int)(getSize().width*.1);
	}
	
	private int yAxisStartY()
	{
		return (int)(getSize().height*.1);
	}
	
	public ActionListener getGraphClear()
	{
		return new graphClearer();
	}
	
	/*public MouseListener getGraphRemove(int which, JPanel me)
	{
		return new graphRemove(which, me);
	}*/
	
	public ActionListener getGraphRemove(int which, JPanel me, JFrame parent)
	{
		return new graphRemove(which, me, parent);
	}
	
	private class graphClearer implements ActionListener
	{

		@Override
		public void actionPerformed(ActionEvent arg0) 
		{
			key.setMaximumSize(new Dimension(new Integer(500), new Integer(100)));
			key.setMinimumSize(new Dimension(new Integer(100), new Integer(100)));
			control.clearData();
			repaint();
		}
	}
	
	/*private class graphRemove implements MouseListener
	{
		private int whichRemove;
		private JPanel me;
		
		public graphRemove(int which, JPanel mine)
		{
			whichRemove=which;
			me=mine;
		}

		@Override
		public void mouseClicked(MouseEvent arg0) {
			// TODO Auto-generated method stub
			control.removeData(whichRemove);
			me.repaint();
			me.validate();
		}

		@Override
		public void mouseEntered(MouseEvent arg0) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void mouseExited(MouseEvent arg0) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void mousePressed(MouseEvent arg0) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void mouseReleased(MouseEvent arg0) {
			// TODO Auto-generated method stub
			
		}
		
	}*/
	
	private class graphRemove implements ActionListener
	{
		private int whichRemove;
		private JPanel me;
		private JFrame parent;
		
		public graphRemove(int which, JPanel mine, JFrame myParent)
		{
			whichRemove=which;
			me=mine;
			parent=myParent;
		}

		@Override
		public void actionPerformed(ActionEvent e) {
			// TODO Auto-generated method stub
			control.removeData(whichRemove);
			me.repaint();
			me.validate();
			me.repaint();
			me.repaint();
			parent.repaint();
			parent.validate();
			parent.repaint();
			System.out.println("HEY");
		}
		
	}
	
}